package tcln.sors.model.product.dom;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.validator.NotNull;

import tcln.sors.model.base.dom.AbstractSorsNamedEntity;
import tcln.sors.model.core.type.Size;

/**
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
@Entity
@Table(name = "TBL_PRODUCT_SPEC")
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "PRODUCT_SPEC_ID")) })
public class ProductSpecification extends AbstractSorsNamedEntity {
    private static final long serialVersionUID = 1L;

    private Size size;
    private Size flattenSize;
    private Double area;
    private String paperFormat;
    private Size paperSize;
    private String faceSpecification;
    private String bottomSpecification;
    private List<ProductSpecProperty> additionalProperties = new ArrayList<ProductSpecProperty>();

    /**
     * Returns current value of {@link #size}.
     * 
     * @return the {@link #size}.
     */
    @NotNull
    @Embedded
    @AttributeOverrides({ @AttributeOverride(name = "width", column = @Column(name = "BOX_WIDTH")),
            @AttributeOverride(name = "height", column = @Column(name = "BOX_HEIGHT")) })
    public Size getSize() {
        return size;
    }

    /**
     * Sets new value for {@link #size}.
     * 
     * @param size
     *            the new size to set
     */
    public void setSize(Size size) {
        this.size = size;
    }

    /**
     * Returns current value of {@link #flattenSize}.
     * 
     * @return the {@link #flattenSize}.
     */
    @Embedded
    @AttributeOverrides({ @AttributeOverride(name = "width", column = @Column(name = "FLATTEN_WIDTH")),
            @AttributeOverride(name = "height", column = @Column(name = "FLATTEN_HEIGHT")) })
    public Size getFlattenSize() {
        return flattenSize;
    }

    /**
     * Sets new value for {@link #flattenSize}.
     * 
     * @param flattenSize
     *            the new flattenSize to set
     */
    public void setFlattenSize(Size flattenSize) {
        this.flattenSize = flattenSize;
    }

    /**
     * Returns current value of {@link #area}.
     * 
     * @return the {@link #area}.
     */
    @Column(name = "AREA")
    public Double getArea() {
        return area;
    }

    /**
     * Sets new value for {@link #area}.
     * 
     * @param area
     *            the new area to set
     */
    public void setArea(Double area) {
        this.area = area;
    }

    /**
     * Returns current value of {@link #paperFormat}.
     * 
     * @return the {@link #paperFormat}.
     */
    @Column(name = "PAPER_FORMAT")
    public String getPaperFormat() {
        return paperFormat;
    }

    /**
     * Sets new value for {@link #paperFormat}.
     * 
     * @param paperFormat
     *            the new paperFormat to set
     */
    public void setPaperFormat(String paperFormat) {
        this.paperFormat = paperFormat;
    }

    /**
     * Returns current value of {@link #paperSize}.
     * 
     * @return the {@link #paperSize}.
     */
    @Embedded
    @AttributeOverrides({ @AttributeOverride(name = "width", column = @Column(name = "PAPER_WIDTH")),
            @AttributeOverride(name = "height", column = @Column(name = "PAPER_HEIGHT")) })
    public Size getPaperSize() {
        return paperSize;
    }

    /**
     * Sets new value for {@link #paperSize}.
     * 
     * @param paperSize
     *            the new paperSize to set
     */
    public void setPaperSize(Size paperSize) {
        this.paperSize = paperSize;
    }

    /**
     * Returns current value of {@link #faceSpecification}.
     * 
     * @return the {@link #faceSpecification}.
     */
    @Column(name = "FACE_SPEC")
    public String getFaceSpecification() {
        return faceSpecification;
    }

    /**
     * Sets new value for {@link #faceSpecification}.
     * 
     * @param faceSpecification
     *            the new faceSpecification to set
     */
    public void setFaceSpecification(String faceSpecification) {
        this.faceSpecification = faceSpecification;
    }

    /**
     * Returns current value of {@link #bottomSpecification}.
     * 
     * @return the {@link #bottomSpecification}.
     */
    @Column(name = "BOTTOM_SPEC")
    public String getBottomSpecification() {
        return bottomSpecification;
    }

    /**
     * Sets new value for {@link #bottomSpecification}.
     * 
     * @param bottomSpecification
     *            the new bottomSpecification to set
     */
    public void setBottomSpecification(String bottomSpecification) {
        this.bottomSpecification = bottomSpecification;
    }

    /**
     * Returns current value of {@link #additionalProperties}.
     * 
     * @return the {@link #additionalProperties}.
     */
    @OneToMany(mappedBy = "productSpecification", fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
    public List<ProductSpecProperty> getAdditionalProperties() {
        return additionalProperties;
    }

    /**
     * Sets new value for {@link #additionalProperties}.
     * 
     * @param additionalProperties
     *            the new additionalProperties to set
     */
    public void setAdditionalProperties(List<ProductSpecProperty> additionalProperties) {
        this.additionalProperties = additionalProperties;
    }
}
